/*
    This file is part of QTau
    Copyright (C) 2013-2018  Tobias "Tomoko" Platen <tplaten@posteo.de>
    Copyright (C) 2013       digited       <https://github.com/digited>
    Copyright (C) 2010-2013  HAL@ShurabaP  <https://github.com/haruneko>

    QTau is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    SPDX-License-Identifier: GPL-3.0+
*/

#include "ui/meter.h"
#include <ui/Config.h>

#include <qevent.h>
#include <qpainter.h>

#include <QTime>
#include <QPixmap>
#include "tempomap.h"
#include "assert.h"
#define __devloglevel__ 4

#include <QMessageBox>
#include "tempomap.h"

const int c_lblcache_hoff = 15; // drawing offset from top-left of octave line
const int c_lblcache_voff = 10;

const QString c_lblcache_font = "Arial";


qtauMeterBar::qtauMeterBar(QWidget *parent) :
    QWidget(parent), _offset(0), _bgCache(nullptr)/*, _labelCache(nullptr)*/
{

}

qtauMeterBar::~qtauMeterBar()
{
    delete _bgCache;
}

void qtauMeterBar::setOffset(int off)
{
    if (off != _offset)
    {
        _offset = off;
        update();
    }
}

void qtauMeterBar::configure2(SNoteSetup &newSetup)
{
    _ns = newSetup;
    int barScreenOffset = 0;
    int lastBar = 128;
    int scale = _ns.note.width() * 4;

    for (int i = 0; i <= lastBar; ++i)
    {
        fraction ts = _ns.tmap->getTimeSignatureForBar(i);
        _ns.barScreenOffsets[i]=barScreenOffset;
        barScreenOffset += scale*ts.numerator*1.0/ts.denominator;


    }
    updateCache();
    update();
}

//---------------------------------------------------------

void qtauMeterBar::paintEvent(QPaintEvent *event)
{
    // draw bg
    int hSt         = event->rect().x() + _offset;
    int firstBar    = _ns.getBarForScreenOffset(hSt);
    int lastBar     = _ns.getBarForScreenOffset (hSt + event->rect().width());

    QRect screenRect(event->rect());
    QRect cacheRect(screenRect);
    cacheRect.moveLeft(cacheRect.x() + hSt);

    QPainter p(this);
    p.drawPixmap(screenRect, *_bgCache, cacheRect);

    // draw bar numbers
    //TODO: get meter events from somewhere

    for (int i = firstBar; i <= lastBar; ++i)
    {
        int barScreenOffset = _ns.barScreenOffsets[i] - _offset;

        //QPainter p(this);
        int c_lblcache_font_size = 12;
        p.setFont(QFont(c_lblcache_font, c_lblcache_font_size));

        QRect lblR(barScreenOffset+5, 0, 200, 20);
        QRect lblR2(barScreenOffset+20, 0, 200, 20);
        QRect lblR3(barScreenOffset+20, 21, 200, 20);

            //lblR.moveTop();
            QString s = QString("%1").arg(i + 1);
            QString s2 = _ns.tmap->getLabel(i,TM_BPM);
            QString s3 = _ns.tmap->getLabel(i,TM_SIG);


            p.drawText(lblR, s);
            if(s2.length()) p.drawText(lblR2, s2);
            if(s3.length()) p.drawText(lblR3, s3);

    }


   // if (!cachedLabels.isEmpty())
    //    p.drawPixmapFragments(cachedLabels.data(), cachedLabels.size(), *_labelCache);
}

void qtauMeterBar::resizeEvent(QResizeEvent*)
{
    updateCache();
}

void qtauMeterBar::mouseDoubleClickEvent(QMouseEvent*)
{

}

void qtauMeterBar::mouseMoveEvent(QMouseEvent*)
{

}

void qtauMeterBar::mousePressEvent(QMouseEvent* evt)
{
    int x=evt->x()+_offset;
    int y=evt->y();
    int bar = _ns.getBarForScreenOffset(x);
    int mode = y-20;
    if(mode<0)
    {
       emit barClicked(bar, TM_BPM);
    }
    if(mode>0)
    {
       emit barClicked(bar, TM_SIG);
    }
}

void qtauMeterBar::mouseReleaseEvent(QMouseEvent*)
{
    //
}

void qtauMeterBar::wheelEvent(QWheelEvent *event)
{
    if (event->modifiers() & Qt::ControlModifier)
        emit zoomed(event->delta());
    else
        emit scrolled(event->delta());
}

void qtauMeterBar::updateCache()
{
    int requiredCacheWidth = _ns.barScreenOffsets[_ns.numBars-1] + _ns.note.width() * 8;

    if (!_bgCache || _bgCache->width() < requiredCacheWidth)
    {
        if (_bgCache)
            delete _bgCache;

        _bgCache = new QPixmap(requiredCacheWidth, geometry().height());
    }

    // prepare painting data
    int vSt  = 0;
    int vEnd = geometry().height();
    int vMid = vEnd * 0.6;

    int bar = 0;
    int beat = 0;
    int pxOff      = 0;

    QVector<QPoint> noteLines;
    QVector<QPoint> barLines;


    //loop1
    while (true)
    {
        if (pxOff >= requiredCacheWidth)
            break;

        fraction time = _ns.tmap->getTimeSignatureForBar(bar); //1

        if (beat==time.numerator) // bar line
        {
            barLines.append(QPoint(pxOff, vSt ));
            barLines.append(QPoint(pxOff, vEnd));
            beat = 1;
            bar++;
            time = _ns.tmap->getTimeSignatureForBar(bar); //2
        }
        else // note line (low)
        {
            noteLines.append(QPoint(pxOff, vMid));
            noteLines.append(QPoint(pxOff, vEnd));
            beat++;
        }

        pxOff += _ns.note.width()* 4.0/time.denominator;

    }
    //DEVLOG_DEBUG("done");

    // paint 'em!
    _bgCache->fill(Qt::white);
    QPainter p(_bgCache);

    p.setPen(QColor(cdef_color_inner_line));
    p.drawLines(noteLines);

    p.setPen(QColor(cdef_color_outer_line));
    p.drawLines(barLines);
}

MeterBarLineEdit::MeterBarLineEdit() : QLineEdit()
{

}

void MeterBarLineEdit::keyPressEvent(QKeyEvent *event)
{
    if(event->key() == Qt::Key_Return || event->key() ==Qt::Key_Enter){
        emit keyPressHooked(event->key());//it works
    }
    else{
        // default handler for event
        QLineEdit::keyPressEvent(event);
    }
}

